using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;

using SBPweb.Themes.Windows;
using SBPweb.Themes.Windows.Skins;

using SBPweb.Controls.Windows.Form;

namespace SBPweb.Controls.Windows.Common
{
	/// <summary>
	/// Class of Form
	/// </summary>
	[ToolboxBitmap(typeof(System.Windows.Forms.Form))]
	public partial class Form : System.Windows.Forms.Form, ISkinnable
	{
		#region Private members

		// skinned form frames 
		private FormCaption formCaption;
		private FormFrameBottom formFrameBottom;
		private FormFrameLeft formFrameLeft;
		private FormFrameRight formFrameRight;

		// skinned small form frames
		private SmallFormCaption smallFormCaption;
		private SmallFormFrameBottom smallFormFrameBottom;
		private SmallFormFrameLeft smallFormFrameLeft;
		private SmallFormFrameRight smallFormFrameRight;

		// paddings of skinned frames
		private Padding mFramePadding = new Padding(0,0,0,0);
		private int mCorner = 5;
		private bool mUseDefaultSkin;
		private Skin mSkin;
		private Color mBackColor = new Color();
		private Color mForeColor = new Color();
		private FormBorderStyle mFormBorderStyle = FormBorderStyle.Sizable;
		private Color mNoSkinBackColor;
		private Color mNoSkinForeColor;

		#endregion

		#region Private properties

		private Padding FramePadding
		{
			get
			{
				return mFramePadding;
			}
			set
			{
				Padding oldValue = mFramePadding;

				mFramePadding = value;

				this.Bounds = new Rectangle(this.Location.X, this.Location.Y,
											this.Size.Width - oldValue.Left - oldValue.Right + value.Left + value.Right,
											this.Size.Height - oldValue.Top - oldValue.Bottom + value.Top + value.Bottom);

				int minWidth = mFramePadding.Left + mFramePadding.Right + 200;
				int minHeight = mFramePadding.Top + mFramePadding.Bottom + 2;
				if (minWidth < this.MinimumSize.Width) minWidth = this.MinimumSize.Width;
				if (minHeight < this.MinimumSize.Height) minHeight = this.MinimumSize.Height;

				this.MinimumSize = new System.Drawing.Size(minWidth, minHeight);

				foreach (Control c in Controls)
				{
					if (
						!c.GetType().Equals(typeof(FormCaption)) &&
						!c.GetType().Equals(typeof(FormFrameBottom)) &&
						!c.GetType().Equals(typeof(FormFrameLeft)) &&
						!c.GetType().Equals(typeof(FormFrameRight)) &&
						!c.GetType().Equals(typeof(SmallFormCaption)) &&
						!c.GetType().Equals(typeof(SmallFormFrameBottom)) &&
						!c.GetType().Equals(typeof(SmallFormFrameLeft)) &&
						!c.GetType().Equals(typeof(SmallFormFrameRight))
						)
					{
						c.Location = new Point(c.Location.X - oldValue.Left + value.Left, c.Location.Y - oldValue.Top + value.Top);
					}
				}

				this.Invalidate(true);
			}
		}

		const int WS_MINIMIZEBOX = 0x20000;
		const int WS_MAXIMIZEBOX = 0x10000;
		const int WS_SYSMENU = 0x80000;
		const int CS_DBLCLKS = 0x8;
		protected override CreateParams CreateParams
		{
			get
			{
				CreateParams cp = base.CreateParams;

				cp.Style = cp.Style | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;
				cp.ClassStyle = CS_DBLCLKS;

				return cp;
			}
		}

		#endregion

		#region Internal properties



		internal bool SmallFrame
		{
			get
			{
				return ((this.FormBorderStyle == FormBorderStyle.FixedToolWindow) || (this.FormBorderStyle == FormBorderStyle.SizableToolWindow) || (this.FormBorderStyle == FormBorderStyle.None));
			}
		}

		internal bool Resizable
		{
			get
			{
				return ((this.FormBorderStyle == FormBorderStyle.Sizable) || (this.FormBorderStyle == FormBorderStyle.SizableToolWindow));
			}
		}

		internal bool DrawIcon
		{
			get
			{
				return this.ControlBox && this.ShowIcon && ((this.FormBorderStyle != FormBorderStyle.FixedSingle) && (this.FormBorderStyle != FormBorderStyle.Fixed3D) && (this.FormBorderStyle != FormBorderStyle.FixedDialog) && (this.FormBorderStyle != FormBorderStyle.FixedToolWindow));
			}
		}

		internal bool MaximizeButton
		{
			get
			{
				return this.ControlBox && this.MaximizeBox && (this.WindowState != FormWindowState.Maximized) && ((this.FormBorderStyle != FormBorderStyle.FixedSingle) && (this.FormBorderStyle != FormBorderStyle.Fixed3D) && (this.FormBorderStyle != FormBorderStyle.FixedDialog) && (this.FormBorderStyle != FormBorderStyle.FixedToolWindow) && (this.FormBorderStyle != FormBorderStyle.SizableToolWindow));
			}
		}

		internal bool RestoreButton
		{
			get
			{
				return this.ControlBox && this.MaximizeBox && (this.WindowState == FormWindowState.Maximized) && ((this.FormBorderStyle != FormBorderStyle.FixedSingle) && (this.FormBorderStyle != FormBorderStyle.Fixed3D) && (this.FormBorderStyle != FormBorderStyle.FixedDialog) && (this.FormBorderStyle != FormBorderStyle.FixedToolWindow) && (this.FormBorderStyle != FormBorderStyle.SizableToolWindow));
			}
		}

		internal bool MinimizeButton
		{
			get
			{
				return this.ControlBox && this.MinimizeBox && ((this.FormBorderStyle != FormBorderStyle.FixedSingle) && (this.FormBorderStyle != FormBorderStyle.Fixed3D) && (this.FormBorderStyle != FormBorderStyle.FixedDialog) && (this.FormBorderStyle != FormBorderStyle.FixedToolWindow) && (this.FormBorderStyle != FormBorderStyle.SizableToolWindow));
			}
		}

		internal bool CloseButton
		{
			get
			{
				return this.ControlBox && (this.FormBorderStyle != FormBorderStyle.None);
			}
		}

		internal new bool HelpButton
		{
			get
			{
				return this.ControlBox && base.HelpButton;
			}
		}


		#endregion

		#region Properties

		public new System.Drawing.Size ClientSize
		{
			get
			{
				return new System.Drawing.Size(base.ClientSize.Width - FramePadding.Left - FramePadding.Right, base.ClientSize.Height - FramePadding.Top - FramePadding.Bottom);
			}
			set
			{
				if (!UseDefaultSkin || Skin == null)
					base.ClientSize = value;
				else
					base.ClientSize = new System.Drawing.Size(value.Width + this.FramePadding.Left + this.FramePadding.Right, value.Height + this.FramePadding.Top + this.FramePadding.Bottom);
			}
		}

		public new System.Drawing.Rectangle ClientRectangle
		{
			get
			{
				return new Rectangle(new Point(FramePadding.Left, FramePadding.Top), this.ClientSize);
			}
		}

		public new FormBorderStyle FormBorderStyle
		{
			get
			{
				if (!UseDefaultSkin || Skin == null)
					return base.FormBorderStyle;
				else
					return mFormBorderStyle;
			}
			set
			{
				mFormBorderStyle = value;
				if (!UseDefaultSkin || Skin == null)
					base.FormBorderStyle = value;
				SetStyle();
				Invalidate(true);
			}
		}

    	#endregion

		#region Constructors

		public Form()
		{
			InitializeLogic();
		}

		public Form(Skin skin)
    	{
			mSkin = skin;
			InitializeLogic();
		}

		public Form(IContainer container)
		{
			container.Add(this);
			InitializeLogic();
		}

		private void InitializeLogic()
		{
			InitializeComponent();
			RegisterEventHandlers();
			SetStyle();
			InitializeColors();
		}

		#endregion

		#region Initialize helpers

		private void InitializeColors()
		{
			if (Skin != null)
			{
				XmlNode cNode = Skin.SelectSingleNode("Elements/Form/Color");
				mBackColor = GetColor(cNode.Attributes["BackColor"]);
				mForeColor = GetColor(cNode.Attributes["ForeColor"]);
			}
		}

		private Color GetColor(XmlAttribute colorAttribute)
		{
			string[] sRGB;
			string sBack = colorAttribute.Value;
			if (sBack.StartsWith("$"))
				sBack = Skin.SelectSingleNode("Colors/" + sBack.Substring(1)).Attributes["Value"].Value;
			sRGB = sBack.Split(',');
			if (sRGB.Length == 3)
				return Color.FromArgb(int.Parse(sRGB[0]), int.Parse(sRGB[1]), int.Parse(sRGB[2]));
			else
				return Color.FromName(sBack);
		}

		private void RegisterEventHandlers()
		{
			DefaultLookAndFeel.OnSkinChanged += new EventHandler(DefaultLookAndFeel_OnSkinChanged);
			this.ControlAdded += new ControlEventHandler(Form_ControlAdded);
			this.ControlRemoved += new ControlEventHandler(Form_ControlRemoved);
		}

		void Form_ControlRemoved(object sender, ControlEventArgs e)
		{
			if (!e.Control.GetType().Equals(typeof(FormCaption)) &&
				!e.Control.GetType().Equals(typeof(FormFrameBottom)) &&
				!e.Control.GetType().Equals(typeof(FormFrameLeft)) &&
				!e.Control.GetType().Equals(typeof(FormFrameRight)) &&
				!e.Control.GetType().Equals(typeof(SmallFormCaption)) &&
				!e.Control.GetType().Equals(typeof(SmallFormFrameBottom)) &&
				!e.Control.GetType().Equals(typeof(SmallFormFrameLeft)) &&
				!e.Control.GetType().Equals(typeof(SmallFormFrameRight)))
				e.Control.Location = new Point(e.Control.Location.X - this.FramePadding.Left, e.Control.Location.Y - this.FramePadding.Top);

			RefreshDockedControls();
		}

		void Form_ControlAdded(object sender, ControlEventArgs e)
		{
			if (!e.Control.GetType().Equals(typeof(FormCaption)) &&
				!e.Control.GetType().Equals(typeof(FormFrameBottom)) &&
				!e.Control.GetType().Equals(typeof(FormFrameLeft)) &&
				!e.Control.GetType().Equals(typeof(FormFrameRight)) &&
				!e.Control.GetType().Equals(typeof(SmallFormCaption)) &&
				!e.Control.GetType().Equals(typeof(SmallFormFrameBottom)) &&
				!e.Control.GetType().Equals(typeof(SmallFormFrameLeft)) &&
				!e.Control.GetType().Equals(typeof(SmallFormFrameRight)))
				e.Control.Location = new Point(e.Control.Location.X + this.FramePadding.Left, e.Control.Location.Y + this.FramePadding.Top);

			RefreshDockedControls();
		}

		private void RefreshDockedControls()
		{

			if (this.SmallFrame)
			{
				if (this.smallFormFrameLeft != null)
				{
					this.smallFormFrameLeft.SendToBack();
					this.smallFormFrameLeft.Dock = DockStyle.Left;
				}
				if (this.smallFormFrameRight != null)
				{
					this.smallFormFrameRight.SendToBack();
					this.smallFormFrameRight.Dock = DockStyle.Right;
				}
				if (this.smallFormCaption != null)
				{
					this.smallFormCaption.SendToBack();
					this.smallFormCaption.Dock = DockStyle.Top;
				}
				if (this.smallFormFrameBottom != null)
				{
					this.smallFormFrameBottom.SendToBack();
					this.smallFormFrameBottom.Dock = DockStyle.Bottom;
				}
			}
			else
			{
				if (this.formFrameLeft != null)
				{
					this.formFrameLeft.SendToBack();
					this.formFrameLeft.Dock = DockStyle.Left;
				}
				if (this.formFrameRight != null)
				{
					this.formFrameRight.SendToBack();
					this.formFrameRight.Dock = DockStyle.Right;
				}
				if (this.formCaption != null)
				{
					this.formCaption.SendToBack();
					this.formCaption.Dock = DockStyle.Top;
				}
				if (this.formFrameBottom != null)
				{
					this.formFrameBottom.SendToBack();
					this.formFrameBottom.Dock = DockStyle.Bottom;
				}
			}

			this.PerformLayout();
		}

		private void SetStyle()
		{
			this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
			
			// skin
			if (Skin != null)
			{
				// save back/foreground colors, if the skin have changed from no skin to skin
				if (this.formCaption == null && this.smallFormCaption == null)
				{
					mNoSkinBackColor = this.BackColor;
					mNoSkinForeColor = this.ForeColor;
				}

				// small
				if (this.SmallFrame && (this.smallFormCaption == null) && (this.FormBorderStyle != FormBorderStyle.None))
				{
					base.FormBorderStyle = FormBorderStyle.None;
					if (this.formCaption != null) DisposeSkinnedFormFrame();
					InitializeSkinnedSmallFormFrame();
				}
				else
					// normal
					if (!this.SmallFrame && (this.formCaption == null) && (this.FormBorderStyle != FormBorderStyle.None))
					{
						base.FormBorderStyle = FormBorderStyle.None;
						if (this.smallFormCaption != null) DisposeSkinnedSmallFormFrame();
						InitializeSkinnedFormFrame();
					}
					else
					    // no border
						if (this.FormBorderStyle == FormBorderStyle.None)
						{
							base.FormBorderStyle = FormBorderStyle.None;
							if (this.formCaption != null) DisposeSkinnedFormFrame();
							if (this.smallFormCaption != null) DisposeSkinnedSmallFormFrame();
						}
				
				this.DoubleBuffered = true;
				this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
				this.SetStyle(ControlStyles.ResizeRedraw, false);
				this.BackColor = mBackColor;
				this.ForeColor = mForeColor;
			}
			// no skin
			else
			{
				base.FormBorderStyle = mFormBorderStyle;

				if (this.formCaption != null) DisposeSkinnedFormFrame();
				if (this.smallFormCaption != null) DisposeSkinnedSmallFormFrame();

				this.BackColor = mNoSkinBackColor;
				this.ForeColor = mNoSkinForeColor;

				this.PerformLayout();
			}
		}

		private void InitializeSkinnedFormFrame()
		{
			this.FramePadding = new Padding(4, 24, 4, 4);

			this.SuspendLayout();

			// Caption
			this.formCaption = new SBPweb.Controls.Windows.Form.FormCaption();
			this.formCaption.UseDefaultSkin = true;
			this.formCaption.Location = new Point(0, 0);
			this.formCaption.Size = new System.Drawing.Size(this.Size.Width, this.FramePadding.Top);
			this.formCaption.TabStop = false;
			this.formCaption.MouseDown += new System.Windows.Forms.MouseEventHandler(this.formCaption_MouseDown);
			this.formCaption.MouseMove += new System.Windows.Forms.MouseEventHandler(this.formCaption_MouseMove);
			this.formCaption.MouseUp += new System.Windows.Forms.MouseEventHandler(this.formCaption_MouseUp);

			// FrameBottom
			this.formFrameBottom = new SBPweb.Controls.Windows.Form.FormFrameBottom();
			this.formFrameBottom.UseDefaultSkin = true;
			this.formFrameBottom.Location = new Point(0, this.Size.Height - this.FramePadding.Bottom);
			this.formFrameBottom.Size = new System.Drawing.Size(this.ClientSize.Width, this.FramePadding.Bottom);
			this.formFrameBottom.TabStop = false;
			this.formFrameBottom.MouseDown += new System.Windows.Forms.MouseEventHandler(this.formFrameBottom_MouseDown);
			this.formFrameBottom.MouseMove += new System.Windows.Forms.MouseEventHandler(this.formFrameBottom_MouseMove);

			// FrameLeft
			this.formFrameLeft = new SBPweb.Controls.Windows.Form.FormFrameLeft();
			this.formFrameLeft.UseDefaultSkin = true;
			this.formFrameLeft.Location = new Point(0, this.FramePadding.Top);
			this.formFrameLeft.Size = new System.Drawing.Size(this.FramePadding.Left, this.Size.Height - this.FramePadding.Top - this.FramePadding.Left);
			this.formFrameLeft.TabStop = false;
			this.formFrameLeft.MouseDown += new System.Windows.Forms.MouseEventHandler(this.formFrameLeft_MouseDown);
			this.formFrameLeft.MouseMove += new System.Windows.Forms.MouseEventHandler(this.formFrameLeft_MouseMove);

			// FrameRight
			this.formFrameRight = new SBPweb.Controls.Windows.Form.FormFrameRight();
			this.formFrameRight.UseDefaultSkin = true;
			this.formFrameRight.Location = new Point(this.Size.Width - this.FramePadding.Right, this.FramePadding.Top);
			this.formFrameRight.TabStop = false;
			this.formFrameRight.Size = new System.Drawing.Size(this.FramePadding.Right, this.ClientSize.Height - this.FramePadding.Top - this.FramePadding.Right);
			this.formFrameRight.MouseDown += new System.Windows.Forms.MouseEventHandler(this.formFrameRight_MouseDown);
			this.formFrameRight.MouseMove += new System.Windows.Forms.MouseEventHandler(this.formFrameRight_MouseMove);

			// Add controls
			this.Controls.Add(this.formCaption);
			this.Controls.Add(this.formFrameRight);
			this.Controls.Add(this.formFrameLeft);
			this.Controls.Add(this.formFrameBottom);

			this.ResumeLayout(false);

			RefreshDockedControls();

			Invalidate(true);
		}

		private void InitializeSkinnedSmallFormFrame()
		{
			this.FramePadding = new Padding(4, 20, 4, 4);

			this.SuspendLayout();

			// Caption
			this.smallFormCaption = new SBPweb.Controls.Windows.Form.SmallFormCaption();
			this.smallFormCaption.UseDefaultSkin = true;
			this.smallFormCaption.Location = new Point(0, 0);
			this.smallFormCaption.Size = new System.Drawing.Size(this.Size.Width, this.FramePadding.Top);
			this.smallFormCaption.TabStop = false;
			this.smallFormCaption.MouseDown += new System.Windows.Forms.MouseEventHandler(this.formCaption_MouseDown);
			this.smallFormCaption.MouseMove += new System.Windows.Forms.MouseEventHandler(this.formCaption_MouseMove);

			// FrameBottom
			this.smallFormFrameBottom = new SBPweb.Controls.Windows.Form.SmallFormFrameBottom();
			this.smallFormFrameBottom.UseDefaultSkin = true;
			this.smallFormFrameBottom.Location = new Point(0, this.Size.Height - this.FramePadding.Bottom);
			this.smallFormFrameBottom.Size = new System.Drawing.Size(this.ClientSize.Width, this.FramePadding.Bottom);
			this.smallFormFrameBottom.TabStop = false;
			this.smallFormFrameBottom.MouseDown += new System.Windows.Forms.MouseEventHandler(this.formFrameBottom_MouseDown);
			this.smallFormFrameBottom.MouseMove += new System.Windows.Forms.MouseEventHandler(this.formFrameBottom_MouseMove);

			// FrameLeft
			this.smallFormFrameLeft = new SBPweb.Controls.Windows.Form.SmallFormFrameLeft();
			this.smallFormFrameLeft.UseDefaultSkin = true;
			this.smallFormFrameLeft.Location = new Point(0, this.FramePadding.Top);
			this.smallFormFrameLeft.Size = new System.Drawing.Size(this.FramePadding.Left, this.Size.Height - this.FramePadding.Top - this.FramePadding.Left);
			this.smallFormFrameLeft.TabStop = false;
			this.smallFormFrameLeft.MouseDown += new System.Windows.Forms.MouseEventHandler(this.formFrameLeft_MouseDown);
			this.smallFormFrameLeft.MouseMove += new System.Windows.Forms.MouseEventHandler(this.formFrameLeft_MouseMove);

			// FrameRight
			this.smallFormFrameRight = new SBPweb.Controls.Windows.Form.SmallFormFrameRight();
			this.smallFormFrameRight.UseDefaultSkin = true;
			this.smallFormFrameRight.Location = new Point(this.ClientSize.Width - this.FramePadding.Right, this.FramePadding.Top);
			this.smallFormFrameRight.Size = new System.Drawing.Size(this.FramePadding.Right, this.Size.Height - this.FramePadding.Top - this.FramePadding.Right);
			this.smallFormFrameRight.TabStop = false;
			this.smallFormFrameRight.MouseDown += new System.Windows.Forms.MouseEventHandler(this.formFrameRight_MouseDown);
			this.smallFormFrameRight.MouseMove += new System.Windows.Forms.MouseEventHandler(this.formFrameRight_MouseMove);

			// Add controls
			this.Controls.Add(this.smallFormCaption);
			this.Controls.Add(this.smallFormFrameRight);
			this.Controls.Add(this.smallFormFrameLeft);
			this.Controls.Add(this.smallFormFrameBottom);

			this.ResumeLayout(false);

			RefreshDockedControls();

			Invalidate(true);
		}

		private void DisposeSkinnedFormFrame()
		{
			this.FramePadding = new Padding(0,0,0,0);

			this.SuspendLayout();

			this.Controls.Remove(this.formCaption);
			this.Controls.Remove(this.formFrameBottom);
			this.Controls.Remove(this.formFrameLeft);
			this.Controls.Remove(this.formFrameRight);

			this.formCaption.Visible = false;
			this.formFrameBottom.Visible = false;
			this.formFrameLeft.Visible = false;
			this.formFrameRight.Visible = false;

			this.formCaption = null;
			this.formFrameBottom = null;
			this.formFrameLeft = null;
			this.formFrameRight = null;

			this.ResumeLayout(false);

			Invalidate(true);
		}

		private void DisposeSkinnedSmallFormFrame()
		{
			this.FramePadding = new Padding(0, 0, 0, 0);

			this.SuspendLayout();

			this.Controls.Remove(this.smallFormCaption);
			this.Controls.Remove(this.smallFormFrameBottom);
			this.Controls.Remove(this.smallFormFrameLeft);
			this.Controls.Remove(this.smallFormFrameRight);

			this.smallFormCaption.Visible = false;
			this.smallFormFrameBottom.Visible = false;
			this.smallFormFrameLeft.Visible = false;
			this.smallFormFrameRight.Visible = false;

			this.smallFormCaption = null;
			this.smallFormFrameBottom = null;
			this.smallFormFrameLeft = null;
			this.smallFormFrameRight = null;

			this.ResumeLayout(false);

			Invalidate(true);
		}

		#endregion

		#region CustomDraw

		protected override void OnPaint(PaintEventArgs e)
		{
			if (Skin == null)
			{
				base.OnPaint(e);
				return;
			}
		}

		protected override void OnPaintBackground(PaintEventArgs e)
		{
			base.OnPaintBackground(e);
		}

		#endregion

		#region Events

		void DefaultLookAndFeel_OnSkinChanged(object sender, EventArgs e)
		{
			InitializeColors();
			SetStyle();
			Invalidate(true);
		}

		#endregion

		#region ISkinnable Members

		/// <summary>
		/// Use default skin?
		/// </summary>
		[Category("Look && feel")]
		public bool UseDefaultSkin
		{
			get
			{
				return mUseDefaultSkin;
			}
			set
			{
				mUseDefaultSkin = value;
				DefaultLookAndFeel_OnSkinChanged(this, null);
			}
		}

		/// <summary>
		/// Used skin
		/// </summary>
		[Category("Look && feel")]
		public Skin Skin
		{
			get
			{
				if (this.UseDefaultSkin)
				{
					return DefaultLookAndFeel.Skin;
				}

				return mSkin;
			}
			set
			{
				mSkin = value;
				Invalidate(true);
			}
		}

		#endregion

		#region Mouse Events

		private Point clickPos;
		private Rectangle clickBounds;

		private void formCaption_MouseDown(object sender, MouseEventArgs e)
		{
			clickPos = e.Location;
			clickBounds = this.Bounds;
		}

		private void formCaption_MouseUp(object sender, MouseEventArgs e)
		{
		}


		private void formCaption_MouseMove(object sender, MouseEventArgs e)
		{
			if (this.WindowState != FormWindowState.Maximized)
			{
				if (Resizable)
				{
					if (!SmallFrame)
					{
						if (e.Y < this.FramePadding.Left && e.X > mCorner && e.X < Bounds.Width - mCorner)
							this.formCaption.Cursor = System.Windows.Forms.Cursors.SizeNS;
						else
							if (e.X < this.FramePadding.Left && e.Y > mCorner)
								this.formCaption.Cursor = System.Windows.Forms.Cursors.SizeWE;
							else
								if (e.X > Bounds.Width - this.FramePadding.Right && e.Y > mCorner)
									this.formCaption.Cursor = System.Windows.Forms.Cursors.SizeWE;
								else
									if ((e.X < this.FramePadding.Left && e.Y <= mCorner) || (e.Y < this.FramePadding.Left && e.X <= mCorner))
										this.formCaption.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
									else
										if ((e.X > Bounds.Width - this.FramePadding.Right && e.Y <= mCorner) || (e.Y < this.FramePadding.Left && e.X >= Bounds.Width - mCorner))
											this.formCaption.Cursor = System.Windows.Forms.Cursors.SizeNESW;
										else
											this.formCaption.Cursor = System.Windows.Forms.Cursors.Default;
					}
					else
					{
						if (e.Y < this.FramePadding.Left && e.X > mCorner && e.X < Bounds.Width - mCorner)
							this.smallFormCaption.Cursor = System.Windows.Forms.Cursors.SizeNS;
						else
							if (e.X < this.FramePadding.Left && e.Y > mCorner)
								this.smallFormCaption.Cursor = System.Windows.Forms.Cursors.SizeWE;
							else
								if (e.X > Bounds.Width - this.FramePadding.Right && e.Y > mCorner)
									this.smallFormCaption.Cursor = System.Windows.Forms.Cursors.SizeWE;
								else
									if ((e.X < this.FramePadding.Left && e.Y <= mCorner) || (e.Y < this.FramePadding.Left && e.X <= mCorner))
										this.smallFormCaption.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
									else
										if ((e.X > Bounds.Width - this.FramePadding.Right && e.Y <= mCorner) || (e.Y < this.FramePadding.Left && e.X >= Bounds.Width - mCorner))
											this.smallFormCaption.Cursor = System.Windows.Forms.Cursors.SizeNESW;
										else
											this.smallFormCaption.Cursor = System.Windows.Forms.Cursors.Default;
					}
				}

				if (e.Button == MouseButtons.Left)
				{
					int diffX = e.X - clickPos.X;
					int diffY = e.Y - clickPos.Y;
					Rectangle bounds = this.Bounds;
					System.Drawing.Size size = bounds.Size;

					if (clickPos.Y < this.FramePadding.Left && clickPos.X > mCorner && clickPos.X < clickBounds.Width - mCorner && Resizable)
					{
						size.Height -= diffY;
						bounds.Y += diffY;
						bounds.Height -= diffY;
					}
					else
						if (clickPos.X < this.FramePadding.Left && clickPos.Y > mCorner && Resizable)
						{
							size.Width -= diffX;
							bounds.X += diffX;
							bounds.Width -= diffX;
						}
						else
							if (clickPos.X > clickBounds.Width - this.FramePadding.Right && clickPos.Y > mCorner && Resizable)
							{
								size.Width += diffX;
								bounds.Width += diffX;
								clickPos.X += diffX;
								clickBounds.Width += diffX;
							}
							else
								if ((clickPos.X < this.FramePadding.Left && clickPos.Y <= mCorner) || (clickPos.Y < this.FramePadding.Left && clickPos.X <= mCorner) && Resizable)
								{
									size.Height -= diffY;
									bounds.Y += diffY;
									bounds.Height -= diffY;
									size.Width -= diffX;
									bounds.X += diffX;
									bounds.Width -= diffX;
								}
								else
									if ((clickPos.X > clickBounds.Width - this.FramePadding.Right && clickPos.Y <= mCorner) || (clickPos.Y < this.FramePadding.Left && clickPos.X >= clickBounds.Width - mCorner) && Resizable)
									{
										size.Width += diffX;
										bounds.Width += diffX;
										clickPos.X += diffX;
										clickBounds.Width += diffX;
										size.Height -= diffY;
										bounds.Y += diffY;
										bounds.Height -= diffY;
									}
									else
									{
										bounds.X += diffX;
										bounds.Y += diffY;
									}

					bounds.Size = size;
					this.Bounds = bounds;
				}
			}
			else
				if (!SmallFrame) this.formCaption.Cursor = System.Windows.Forms.Cursors.Default;
				else this.smallFormCaption.Cursor = System.Windows.Forms.Cursors.Default;
		}
			
		private void formFrameBottom_MouseDown(object sender, MouseEventArgs e)
		{
			clickPos = e.Location;
			clickBounds = this.Bounds;
		}

		private void formFrameBottom_MouseMove(object sender, MouseEventArgs e)
		{
			if (this.WindowState != FormWindowState.Maximized && Resizable)
			{
				if (!SmallFrame)
				{
					if (e.X < mCorner)
						this.formFrameBottom.Cursor = System.Windows.Forms.Cursors.SizeNESW;
					else if (e.X > this.Bounds.Width - mCorner)
						this.formFrameBottom.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
					else
						this.formFrameBottom.Cursor = System.Windows.Forms.Cursors.SizeNS;
				}
				else
				{
					if (e.X < mCorner)
						this.smallFormFrameBottom.Cursor = System.Windows.Forms.Cursors.SizeNESW;
					else if (e.X > this.Bounds.Width - mCorner)
						this.smallFormFrameBottom.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
					else
						this.smallFormFrameBottom.Cursor = System.Windows.Forms.Cursors.SizeNS;
				}

				if (e.Button == MouseButtons.Left)
				{
					Rectangle bounds = this.Bounds;
					System.Drawing.Size size = bounds.Size;
					size.Height += (e.Y - clickPos.Y);

					if (clickPos.X < mCorner)
					{
						int diff = e.X - clickPos.X;
						size.Width -= diff;
						clickBounds.Width += diff;
						bounds.X += diff;
					}
					else if (clickPos.X > clickBounds.Width - mCorner)
					{
						int diff = e.X - clickPos.X;
						size.Width += diff;
						clickPos.X += diff;
						clickBounds.Width += diff;
					}
					bounds.Size = size;
					this.Bounds = bounds;
				}
			}
			else
				if (!SmallFrame) this.formFrameBottom.Cursor = System.Windows.Forms.Cursors.Default;
				else this.smallFormFrameBottom.Cursor = System.Windows.Forms.Cursors.Default;
		}

		private void formFrameRight_MouseDown(object sender, MouseEventArgs e)
		{
			clickPos = e.Location;
			clickBounds = this.Bounds;
		}

		private void formFrameRight_MouseMove(object sender, MouseEventArgs e)
		{
			if (this.WindowState != FormWindowState.Maximized && Resizable)
			{
				if (!SmallFrame)
				{
					if (e.Y > this.Bounds.Height - this.FramePadding.Top - mCorner)
						this.formFrameRight.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
					else
						this.formFrameRight.Cursor = System.Windows.Forms.Cursors.SizeWE;
				}
				else
				{
					if (e.Y > this.Bounds.Height - this.FramePadding.Top - mCorner)
						this.smallFormFrameRight.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
					else
						this.smallFormFrameRight.Cursor = System.Windows.Forms.Cursors.SizeWE;
				}

				if (e.Button == MouseButtons.Left)
				{
					Rectangle bounds = this.Bounds;
					System.Drawing.Size size = bounds.Size;
					size.Width += (e.X - clickPos.X);

					if (clickPos.Y > clickBounds.Height - this.FramePadding.Top - mCorner)
					{
						int diff = e.Y - clickPos.Y;
						size.Height += diff;
						clickPos.Y += diff;
						clickBounds.Height += diff;
					}

					bounds.Size = size;
					this.Bounds = bounds;
				}
			}
			else
				if (!SmallFrame) this.formFrameRight.Cursor = System.Windows.Forms.Cursors.Default;
				else this.smallFormFrameRight.Cursor = System.Windows.Forms.Cursors.Default;
		}

		private void formButtonClose_Click(object sender, EventArgs e)
		{
			this.Close();
		}

		private void formFrameLeft_MouseDown(object sender, MouseEventArgs e)
		{
			clickPos = e.Location;
			clickBounds = this.Bounds;
		}

		private void formFrameLeft_MouseMove(object sender, MouseEventArgs e)
		{
			if (this.WindowState != FormWindowState.Maximized && Resizable)
			{
				if (!SmallFrame)
				{
					if (e.Y > this.Bounds.Height - this.FramePadding.Top - mCorner)
						this.formFrameLeft.Cursor = System.Windows.Forms.Cursors.SizeNESW;
					else
						this.formFrameLeft.Cursor = System.Windows.Forms.Cursors.SizeWE;
				}
				else
				{
					if (e.Y > this.Bounds.Height - this.FramePadding.Top - mCorner)
						this.smallFormFrameLeft.Cursor = System.Windows.Forms.Cursors.SizeNESW;
					else
						this.smallFormFrameLeft.Cursor = System.Windows.Forms.Cursors.SizeWE;
				}

				if (e.Button == MouseButtons.Left)
				{
					Rectangle bounds = this.Bounds;
					System.Drawing.Size size = bounds.Size;
					int diff = e.X - clickPos.X;
					size.Width -= diff;
					bounds.X += diff;
					if (clickPos.Y > clickBounds.Height - this.FramePadding.Top - mCorner)
					{
						size.Width -= diff;
						clickBounds.Width += diff;
						bounds.X += diff;
					}
					bounds.Size = size;
					this.Bounds = bounds;
				}
			}
			else
				if (!SmallFrame) this.formFrameLeft.Cursor = System.Windows.Forms.Cursors.Default;
				else this.smallFormFrameLeft.Cursor = System.Windows.Forms.Cursors.Default;
		}
	
		#endregion
	}
}
